package com.lysj.bhp.util.web;

import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 参数工具类
 * 
 * @author soul
 */
public class ParamUtil {

	/**
	 * 判断一个集合对象是否为null或者为空集合
	 * 
	 * @return
	 */
	public static boolean isBlack(Collection<?> collection) {
		return collection == null || collection.size() == 0;
	}

	/**
	 * 判断一个字符串是否为null或者为空
	 * 
	 * @return
	 */
	public static boolean isBlack(String string) {
		return string == null || string.trim().equals("");
	}

	/**
	 * 判断数字是否为null或者为0
	 * 
	 * @return
	 */
	public static boolean isBlack(Number num) {
		return num == null || num.longValue() == 0;
	}

	/**
	 * 判断一个long[]是否为null或者长度为0
	 * 
	 * @return
	 */
	public static boolean isBlack(Long[] ids) {
		return ids == null || ids.length == 0;
	}

	/**
	 * 判断一个String[]是否为null或者长度为0
	 * 
	 * @return
	 */
	public static boolean isBlack(String[] strings) {
		return strings == null || strings.length == 0;
	}

	/**
	 * 判断一个Object是否为null
	 * 
	 * @return
	 */
	public static boolean isBlack(Object obj) {
		return obj == null;
	}

	/**
	 * 校验一个字符串是否为空指针或者空字符串并去前后空格
	 * 
	 * @param string
	 * @return 32位MD5摘要过后的字符串
	 */
	public static String md5(String string) {
		if (string == null || string.trim().equals("")) {
			return null;
		}
		try {
			MessageDigest digest = MessageDigest.getInstance("md5");
			byte[] data = digest.digest(string.getBytes("utf-8"));
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < data.length; i++) {
				String result = Integer.toHexString(data[i] & 0xff);
				String temp = null;
				if (result.length() == 1) {
					temp = "0" + result;
				} else {
					temp = result;
				}
				sb.append(temp);
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 生成uuid
	 * 
	 * @param string
	 * @return 32位的UUID字符串
	 */
	public static String uuid() {
		return UUID.randomUUID().toString().toUpperCase().replace("-", "");
	}

	/**
	 * 从一个字符串中获取数字
	 * 
	 * @param str
	 * @return
	 */
	public static String selectNum(String str) {
		String regEx = "[^0-9]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		return m.replaceAll("").trim();
	}

	/**
	 * @author zk
	 * @date 2018/2/9 14:21
	 * @Description JPA构建通用查询条件 目前尚未完善 仅覆盖int、long及其包装类和String
	 */
	public static Specification createSpecification(Object model){

		Specification specification = new Specification() {
			@Override
			public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<>();
				// 得到类对象
				Class cls = (Class) model.getClass();
				/* 得到类中的所有属性集合 */
				Field[] fs = cls.getDeclaredFields();
				for (int i = 0; i < fs.length; i++) {
					Field f = fs[i];
					if(f.getName().equals("token")){
						continue;
					}
					if(f.getName().equals("limit")){
						continue;
					}
					if(f.getName().equals("offset")){
						continue;
					}
					if(f.getName().equals("page")){
						continue;
					}
					f.setAccessible(true); // 设置些属性是可以访问的
					Object val = new Object();
					try {
						val = f.get(model);
						if(!ParamUtil.isBlack(val)){
							if(String.class.equals(f.getType())){
								String s = (String)val;
								if(!ParamUtil.isBlack(s)){
									predicates.add(criteriaBuilder.like(root.get(f.getName()),"%"+val+"%"));
								}
							}else if( Long.class.equals(f.getType()) || long.class.equals(f.getType())){
								if(val.equals(0)){
									continue;
								}
								Long l = (Long)val;
								if (!ParamUtil.isBlack(l)) {
									predicates.add(criteriaBuilder.equal(root.get(f.getName()),val));
								}
							}else if(Integer.class.equals(f.getType()) || int.class.equals(f.getType())){
								if(val.equals(0)){
									continue;
								}
								Integer l = (Integer) val;
								if (!ParamUtil.isBlack(l)) {
									predicates.add(criteriaBuilder.equal(root.get(f.getName()),val));
								}
							}else if(Date.class.equals(f.getType()) && (f.getName().startsWith("begin_") || f.getName().startsWith("end_"))){
								Date d = (Date) val;
								String[] name = f.getName().split("_");
								if(!ParamUtil.isBlack(d)){
									if(name[0].equals("begin")){
										predicates.add(criteriaBuilder.greaterThan(root.get(name[1]), d));
									}else if(name[0].equals("end")){
										predicates.add(criteriaBuilder.lessThan(root.get(name[1]), d));
									}else {
										break;
									}
								}
							}
						}
						// 得到此属性的值
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
				return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
			}
		};
		return specification;
	}
}
